#ifndef COMPILERCOMMANDGENERATOR_H
#define COMPILERCOMMANDGENERATOR_H

#include <map>

#include <wx/string.h>
#include <wx/dynarray.h>
#include "compiletargetbase.h"

class M_Code_Project;
class ProjectBuildTarget;
class ProjectFile;
class Compiler;

typedef std::map<ProjectBuildTarget*, wxString> OptionsMap;
typedef std::map<ProjectBuildTarget*, wxArrayString> SearchDirsMap;


class CompilerCommandGenerator {
  public:
    CompilerCommandGenerator();
    virtual ~CompilerCommandGenerator();
    virtual void Init( M_Code_Project* project );
    virtual void GenerateCommandLine( wxString& macro, ProjectBuildTarget* target, ProjectFile* pf, const wxString& file,
                                      const wxString& object, const wxString& flat_object, const wxString& deps );
    virtual const wxArrayString& GetCompilerSearchDirs( ProjectBuildTarget* target );
    virtual const wxArrayString& GetLinkerSearchDirs( ProjectBuildTarget* target );
  protected:
    virtual void DoBuildScripts( M_Code_Project* project, CompileTargetBase* target, const wxString& funcName );
    virtual wxString GetOrderedOptions( const ProjectBuildTarget* target, OptionsRelationType rel, const wxString& project_options, const wxString& target_options );
    virtual wxArrayString GetOrderedOptions( const ProjectBuildTarget* target, OptionsRelationType rel, const wxArrayString& project_options, const wxArrayString& target_options );
    virtual wxArrayString GetOrderedIncludeDirs( Compiler* compiler, ProjectBuildTarget* target );
    virtual wxArrayString GetOrderedLibrariesDirs( Compiler* compiler, ProjectBuildTarget* target );
    virtual wxArrayString GetOrderedResourceIncludeDirs( Compiler* compiler, ProjectBuildTarget* target );
    static wxString MakeOptString( const wxArrayString& arr, const wxString& opt, wxChar separator = _T( ' ' ) );
    static wxString PathSearch( const wxArrayString& arr, const wxString& filename );
    virtual wxString SetupOutputFilenames( Compiler* compiler, ProjectBuildTarget* target );
    virtual wxString SetupIncludeDirs( Compiler* compiler, ProjectBuildTarget* target );
    virtual wxString SetupLibrariesDirs( Compiler* compiler, ProjectBuildTarget* target );
    virtual wxString SetupResourceIncludeDirs( Compiler* compiler, ProjectBuildTarget* target );
    virtual wxString SetupCompilerOptions( Compiler* compiler, ProjectBuildTarget* target );
    virtual wxString SetupLinkerOptions( Compiler* compiler, ProjectBuildTarget* target );
    virtual wxString SetupLinkLibraries( Compiler* compiler, ProjectBuildTarget* target );
    virtual wxString SetupResourceCompilerOptions( Compiler* compiler, ProjectBuildTarget* target );
    virtual wxString FixupLinkLibraries( Compiler* compiler, const wxString& lib );
    virtual void FixPathSeparators( Compiler* compiler, wxString& inAndOut );
    OptionsMap m_Output;
    OptionsMap m_StaticOutput;
    OptionsMap m_DefOutput;
    OptionsMap m_Inc;
    OptionsMap m_Lib;
    OptionsMap m_CFlags;
    OptionsMap m_LDFlags;
    OptionsMap m_LDAdd;
    wxString m_PrjIncPath;
    SearchDirsMap m_CompilerSearchDirs;
    SearchDirsMap m_LinkerSearchDirs;
  private:
    wxString GetProcessedIncludeDir( Compiler* compiler, ProjectBuildTarget* target,
                                     const wxArrayString& inc_dirs, const wxString& inc_switch );
    void SearchDirsFromBackticks( Compiler* compiler, ProjectBuildTarget* target, const wxString& btOutput );
    wxArrayString m_NotLoadedScripts;
    wxArrayString m_ScriptsWithErrors;
};

#endif
